package com.movie.controller;

import com.movie.dto.AdminDTO;
import com.movie.entity.Admin;
import com.movie.service.AdminService;
import com.movie.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/admin")
@CrossOrigin(origins = "http://localhost:5173")
public class AdminController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 管理员登录
     * @param loginAdmin 登录信息
     * @return 登录结果
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody Admin loginAdmin) {
        String username = loginAdmin.getUsername();
        String password = loginAdmin.getPassword();

        try {
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
            );
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            // 检查是否确实是管理员 (可选，如果 UserDetailsService 返回了角色信息)
            if (!userDetails.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"))) {
                 return ResponseEntity.status(403).body("User is not an admin");
            }

            final String jwt = jwtUtil.generateToken(userDetails);
            return ResponseEntity.ok(Map.of("token", jwt));

        } catch (Exception e) {
            return ResponseEntity.status(401).body("Invalid admin credentials");
        }
    }

    /**
     * 获取管理员信息
     * @param id 管理员ID
     * @return 管理员信息
     */
    @GetMapping("/{id}")
    public ResponseEntity<?> getAdminById(@PathVariable Long id) {
        Admin admin = adminService.getAdminById(id);
        if (admin != null) {
            // 返回 AdminDTO
            AdminDTO adminDTO = new AdminDTO();
            adminDTO.setId(admin.getId());
            adminDTO.setUsername(admin.getUsername());
            return ResponseEntity.ok(adminDTO);
        }
        return ResponseEntity.notFound().build();
    }

    /**
     * 更新管理员信息
     * @param id 管理员ID
     * @param adminDetails 管理员信息
     * @return 更新结果
     */
    @PutMapping("/{id}")
    public ResponseEntity<?> updateAdmin(@PathVariable Long id, @RequestBody Admin adminDetails) {
        // 注意：只允许更新用户名，其他信息（如密码）应通过专用接口修改
        Admin admin = adminService.getAdminById(id);
        if (admin != null) {
            // 只更新用户名
            if (adminDetails.getUsername() != null && !adminDetails.getUsername().equals(admin.getUsername())) {
                // (可选) 检查新用户名是否已存在
                // Admin existingWithNewUsername = adminService.getAdminByUsername(adminDetails.getUsername());
                // if (existingWithNewUsername != null) {
                //     return ResponseEntity.status(HttpStatus.CONFLICT).body(Map.of("message", "Username already exists"));
                // }
                admin.setUsername(adminDetails.getUsername());
                // 调用 Mapper 直接更新用户名，或者在 Service 中添加 updateUsername 方法
                // 这里假设直接操作实体，依赖于 JPA/Hibernate 的自动脏检查更新，或者在 Service 中添加特定方法
                // adminService.updateUsername(id, adminDetails.getUsername()); // 假设有这个方法

                // **重要**: 由于我们移除了 updateAdmin Service 方法，
                // **这里暂时不执行实际的数据库更新操作。**
                // 需要决定如何处理管理员信息更新。是添加 updateUsername Service 方法？
                // 还是认为管理员信息基本不变，只允许改密码？
            }

            // 返回更新后的（或未变的）管理员信息 DTO
            AdminDTO adminDTO = new AdminDTO();
            adminDTO.setId(admin.getId());
            adminDTO.setUsername(admin.getUsername()); // 返回当前数据库中的用户名
            return ResponseEntity.ok(adminDTO);
        }
        return ResponseEntity.notFound().build();
    }

    /**
     * 修改管理员密码
     * @param id 管理员ID
     * @param passwordRequest 包含当前密码和新密码的请求体
     * @return 修改结果
     */
    @PostMapping("/{id}/change-password")
    public ResponseEntity<?> changePassword(
            @PathVariable Long id,
            @RequestBody Map<String, String> passwordRequest) {

        String currentPassword = passwordRequest.get("currentPassword");
        String newPassword = passwordRequest.get("newPassword");

        if (currentPassword == null || newPassword == null) {
            Map<String, String> response = new HashMap<>();
            response.put("message", "当前密码和新密码不能为空");
            return ResponseEntity.badRequest().body(response);
        }

        try {
            Admin admin = adminService.getAdminById(id);
            if (admin == null) {
                return ResponseEntity.notFound().build();
            }

            // 使用 PasswordEncoder 验证当前密码
            if (!passwordEncoder.matches(currentPassword, admin.getPassword())) {
                Map<String, String> response = new HashMap<>();
                response.put("message", "当前密码不正确");
                return ResponseEntity.badRequest().body(response);
            }

            // 加密新密码并调用新的 Service 方法
            String newPasswordHash = passwordEncoder.encode(newPassword);
            adminService.updatePassword(id, newPasswordHash);

            Map<String, String> response = new HashMap<>();
            response.put("message", "密码修改成功");
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            Map<String, String> response = new HashMap<>();
            response.put("message", "密码修改失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }
}
